<!DOCTYPE html>
<html>
<head>
    <title>PlayCanvas Wobble Shader</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
    <link rel="icon" type="image/png" href="../playcanvas-favicon.png" />
    <script src="../../build/output/playcanvas.js"></script>
    <style>
        body { 
            margin: 0;
            overflow-y: hidden;
        }
    </style>
</head>

<body>
    <!-- The canvas element -->
    <canvas id="application-canvas"></canvas>

    <!-- shaders -->
    <script id="vshader" type="x-shader/x-vertex">
        attribute vec3 aPosition;
        attribute vec2 aUv0;

        uniform mat4 matrix_model;
        uniform mat4 matrix_viewProjection;
        uniform float uTime;

        varying vec2 vUv0;

        void main(void)
        {
            vec4 pos = matrix_model * vec4(aPosition, 1.0);
            pos.x += sin(uTime + pos.y * 4.0) * 0.1;
            vUv0 = aUv0;
            gl_Position = matrix_viewProjection * pos;
        }
    </script>

    <script id="fshader" type="x-shader/x-fragment">
        precision highp float;

        uniform sampler2D uDiffuseMap;

        varying vec2 vUv0;

        void main(void)
        {
            gl_FragColor = texture2D(uDiffuseMap, vUv0);
        }
    </script>

    <!-- The script -->
    <script>
        var entity, light, camera;
        var time = 0;
        var shader, material, diffuseMap;

        var canvas = document.getElementById("application-canvas");

        // Create the application and start the update loop
        var app = new pc.Application(canvas);
        app.start();

        // Set the canvas to fill the window and automatically change resolution to be the same as the canvas size
        app.setCanvasFillMode(pc.FILLMODE_FILL_WINDOW);
        app.setCanvasResolution(pc.RESOLUTION_AUTO);

        window.addEventListener("resize", function () {
            app.resizeCanvas(canvas.width, canvas.height);
        });

        app.scene.ambientLight = new pc.Color(0.2, 0.2, 0.2);

        // Create an Entity with a camera component
        camera = new pc.Entity();
        camera.addComponent("camera", {
            clearColor: new pc.Color(0.4, 0.45, 0.5)
        });
        camera.translate(0, 7, 25);

        // Create an Entity with a point light component and a sphere model component.
        light = new pc.Entity();
        light.addComponent("light", {
            type: "point",
            color: new pc.Color(1, 1, 1),
            radius: 10
        });
        light.translate(0, 1, 0);

        // Add entities into scene hierarchy
        app.root.addChild(camera);
        app.root.addChild(light);

        var url = "../assets/models/statue/statue.json";
        app.assets.loadFromUrl(url, "model", function (err, asset) {
            entity = new pc.Entity();

            var modelComponent = entity.addComponent("model", {
                type: "asset",
                asset: asset
            });
            app.root.addChild(entity);

            var model = modelComponent.model;

            var gd = app.graphicsDevice;

            var shaderDefinition = {
                attributes: {
                    aPosition: pc.SEMANTIC_POSITION,
                    aUv0: pc.SEMANTIC_TEXCOORD0
                },
                vshader: document.getElementById("vshader").textContent,
                fshader: document.getElementById("fshader").textContent
            };

            shader = new pc.Shader(gd, shaderDefinition);

            diffuseMap = model.getMaterials()[0].diffuseMap;

            material = new pc.Material();

            material.shader = this.shader;
            material.setParameter('uTime', 0);
            material.setParameter('uDiffuseMap', diffuseMap);

            model.meshInstances.forEach(function (meshInstance) {
                meshInstance.material = material;
            });

            app.on("update", function (dt) {
                time += dt;
                material.setParameter('uTime', time);
            });

        });
    </script>
</body>
</html>
